<!-- HTML header for doxygen 1.8.18-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.18"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>Ipopt: Implementation Details</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
  $(document).ready(function() { init_search(); });
/* @license-end */
</script>
<script type="text/x-mathjax-config">
  MathJax.Hub.Config({
    extensions: ["tex2jax.js"],
    jax: ["input/TeX","output/HTML-CSS"],
});
</script>
<script type="text/javascript" async="async" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js"></script>
<link href="stylesheet.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 40px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">Ipopt Documentation
   &#160;<!--span id="projectnumber">3.14.12</span-->
   </div>
  </td>
   <td>        <div id="MSearchBox" class="MSearchBoxInactive">
        <span class="left">
          <img id="MSearchSelect" src="search/mag_sel.png"
               onmouseover="return searchBox.OnSearchSelectShow()"
               onmouseout="return searchBox.OnSearchSelectHide()"
               alt=""/>
          <input type="text" id="MSearchField" value="Search" accesskey="S"
               onfocus="searchBox.OnSearchFieldFocus(true)" 
               onblur="searchBox.OnSearchFieldFocus(false)" 
               onkeyup="searchBox.OnSearchFieldChange(event)"/>
          </span><span class="right">
            <a id="MSearchClose" href="javascript:searchBox.CloseResultsWindow()"><img id="MSearchCloseImg" border="0" src="search/close.png" alt=""/></a>
          </span>
        </div>
</td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.18 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
  <div id="nav-tree">
    <div id="nav-tree-contents">
      <div id="nav-sync" class="sync"></div>
    </div>
  </div>
  <div id="splitbar" style="-moz-user-select:none;" 
       class="ui-resizable-handle">
  </div>
</div>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(document).ready(function(){initNavTree('IMPL.html',''); initResizable(); });
/* @license-end */
</script>
<div id="doc-content">
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div class="PageDoc"><div class="header">
  <div class="headertitle">
<div class="title">Implementation Details </div>  </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><h1><a class="anchor" id="TRIPLET"></a>
Triplet Format for Sparse Matrices</h1>
<p>Ipopt was designed for optimizing large sparse nonlinear programs. Because of problem sparsity, the required matrices (like the constraints Jacobian or Lagrangian Hessian) are not stored as dense matrices, but rather in a sparse matrix format. For the tutorials in this document, we use the triplet format. Consider the matrix </p><p class="formulaDsp">
\[ \left[ \begin{array}{ccccccc} 1.1 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0.5 \\ 0 &amp; 1.9 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0.5 \\ 0 &amp; 0 &amp; 2.6 &amp; 0 &amp; 0 &amp; 0 &amp; 0.5 \\ 0 &amp; 0 &amp; 7.8 &amp; 0.6 &amp; 0 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 1.5 &amp; 2.7 &amp; 0 &amp; 0 \\ 1.6 &amp; 0 &amp; 0 &amp; 0 &amp; 0.4 &amp; 0 &amp; 0 \\ 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0 &amp; 0.9 &amp; 1.7 \\ \end{array} \right] \]
</p>
<p>A standard dense matrix representation would need to store 7 * 7 = 49 floating point numbers, where many entries would be zero. In triplet format, however, only the nonzero entries are stored. The triplet format records the row number, the column number, and the value of all nonzero entries in the matrix. For the matrix above, this means storing 14 integers for the rows, 14 integers for the columns, and 14 floating point numbers for the values. While this does not seem like a huge space saving over the 49 floating point numbers stored in the dense representation, for larger matrices, the space savings are very dramatic. (For an \(n \times n\) matrix, the dense representation grows with the the square of \(n\), while the sparse representation grows linearly in the number of nonzeros.)</p>
<p>The parameter <code>index_style</code> in <a class="el" href="classIpopt_1_1TNLP.html#a5da5791365764706aeda02b78f7719b6" title="Method to request the initial information about the problem.">Ipopt::TNLP::get_nlp_info</a> tells Ipopt if you prefer to use C style indexing (0-based, i.e., starting the counting at 0) for the row and column indices or Fortran style (1-based). The following table shows the triplet format for the above example matrix when using the Fortran indexing style.</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadLeft">row </th><th class="markdownTableHeadLeft">col </th><th class="markdownTableHeadLeft">value  </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[0] = 1 </td><td class="markdownTableBodyLeft">jCol[0] = 1 </td><td class="markdownTableBodyLeft">values[0] = 1.1  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[1] = 1 </td><td class="markdownTableBodyLeft">jCol[1] = 7 </td><td class="markdownTableBodyLeft">values[1] = 0.5  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[2] = 2 </td><td class="markdownTableBodyLeft">jCol[2] = 2 </td><td class="markdownTableBodyLeft">values[2] = 1.9  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[3] = 2 </td><td class="markdownTableBodyLeft">jCol[3] = 7 </td><td class="markdownTableBodyLeft">values[3] = 0.5  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[4] = 3 </td><td class="markdownTableBodyLeft">jCol[4] = 3 </td><td class="markdownTableBodyLeft">values[4] = 2.6  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[5] = 3 </td><td class="markdownTableBodyLeft">jCol[5] = 7 </td><td class="markdownTableBodyLeft">values[5] = 0.5  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[6] = 4 </td><td class="markdownTableBodyLeft">jCol[6] = 3 </td><td class="markdownTableBodyLeft">values[6] = 7.8  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[7] = 4 </td><td class="markdownTableBodyLeft">jCol[7] = 4 </td><td class="markdownTableBodyLeft">values[7] = 0.6  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[8] = 5 </td><td class="markdownTableBodyLeft">jCol[8] = 4 </td><td class="markdownTableBodyLeft">values[8] = 1.5  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[9] = 5 </td><td class="markdownTableBodyLeft">jCol[9] = 5 </td><td class="markdownTableBodyLeft">values[9] = 2.7  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[10] = 6 </td><td class="markdownTableBodyLeft">jCol[10] = 1 </td><td class="markdownTableBodyLeft">values[10] = 1.6  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[11] = 6 </td><td class="markdownTableBodyLeft">jCol[11] = 5 </td><td class="markdownTableBodyLeft">values[11] = 0.4  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[12] = 7 </td><td class="markdownTableBodyLeft">jCol[12] = 6 </td><td class="markdownTableBodyLeft">values[12] = 0.9  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[13] = 7 </td><td class="markdownTableBodyLeft">jCol[13] = 7 </td><td class="markdownTableBodyLeft">values[13] = 1.7  </td></tr>
</table>
<p>When using the C indexing style, the above example matrix in triplet format is the following:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadNone">row </th><th class="markdownTableHeadNone">col </th><th class="markdownTableHeadNone">value  </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[0] = 0 </td><td class="markdownTableBodyNone">jCol[0] = 0 </td><td class="markdownTableBodyNone">values[0] = 1.1  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[1] = 0 </td><td class="markdownTableBodyNone">jCol[1] = 6 </td><td class="markdownTableBodyNone">values[1] = 0.5  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[2] = 1 </td><td class="markdownTableBodyNone">jCol[2] = 1 </td><td class="markdownTableBodyNone">values[2] = 1.9  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[3] = 1 </td><td class="markdownTableBodyNone">jCol[3] = 6 </td><td class="markdownTableBodyNone">values[3] = 0.5  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[4] = 2 </td><td class="markdownTableBodyNone">jCol[4] = 2 </td><td class="markdownTableBodyNone">values[4] = 2.6  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[5] = 2 </td><td class="markdownTableBodyNone">jCol[5] = 6 </td><td class="markdownTableBodyNone">values[5] = 0.5  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[6] = 3 </td><td class="markdownTableBodyNone">jCol[6] = 2 </td><td class="markdownTableBodyNone">values[6] = 7.8  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[7] = 3 </td><td class="markdownTableBodyNone">jCol[7] = 3 </td><td class="markdownTableBodyNone">values[7] = 0.6  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[8] = 4 </td><td class="markdownTableBodyNone">jCol[8] = 3 </td><td class="markdownTableBodyNone">values[8] = 1.5  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[9] = 4 </td><td class="markdownTableBodyNone">jCol[9] = 4 </td><td class="markdownTableBodyNone">values[9] = 2.7  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[10] = 5 </td><td class="markdownTableBodyNone">jCol[10] = 0 </td><td class="markdownTableBodyNone">values[10] = 1.6  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[11] = 5 </td><td class="markdownTableBodyNone">jCol[11] = 4 </td><td class="markdownTableBodyNone">values[11] = 0.4  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyNone">iRow[12] = 6 </td><td class="markdownTableBodyNone">jCol[12] = 5 </td><td class="markdownTableBodyNone">values[12] = 0.9  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyNone">iRow[13] = 6 </td><td class="markdownTableBodyNone">jCol[13] = 6 </td><td class="markdownTableBodyNone">values[13] = 1.7  </td></tr>
</table>
<p>The individual elements of the matrix can be listed in any order, and if there are multiple items for the same nonzero position, the values provided for those positions are added.</p>
<p>The Hessian of the Lagrangian is a symmetric matrix. In the case of a symmetric matrix, you only need to specify the lower left triangular part (or, alternatively, the upper right triangular part). For example, given the matrix </p><p class="formulaDsp">
\[ \left[ \begin{array}{ccccccc} 1.0 &amp; 0 &amp; 3.0 &amp; 0 &amp; 2.0 \\ 0 &amp; 1.1 &amp; 0 &amp; 0 &amp; 5.0 \\ 3.0 &amp; 0 &amp; 1.2 &amp; 6.0 &amp; 0 \\ 0 &amp; 0 &amp; 6.0 &amp; 1.3 &amp; 9.0 \\ 2.0 &amp; 5.0 &amp; 0 &amp; 9.0 &amp; 1.4 \end{array} \right], \]
</p>
<p> the triplet format is shown in the following tables for the Fortran and C index styles, respectively:</p>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadLeft">row </th><th class="markdownTableHeadLeft">col </th><th class="markdownTableHeadLeft">value  </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[0] = 1 </td><td class="markdownTableBodyLeft">jCol[0] = 1 </td><td class="markdownTableBodyLeft">values[0] = 1.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[1] = 2 </td><td class="markdownTableBodyLeft">jCol[1] = 2 </td><td class="markdownTableBodyLeft">values[1] = 1.1  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[2] = 3 </td><td class="markdownTableBodyLeft">jCol[2] = 1 </td><td class="markdownTableBodyLeft">values[2] = 3.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[3] = 3 </td><td class="markdownTableBodyLeft">jCol[3] = 3 </td><td class="markdownTableBodyLeft">values[3] = 1.2  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[4] = 4 </td><td class="markdownTableBodyLeft">jCol[4] = 3 </td><td class="markdownTableBodyLeft">values[4] = 6.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[5] = 4 </td><td class="markdownTableBodyLeft">jCol[5] = 4 </td><td class="markdownTableBodyLeft">values[5] = 1.3  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[6] = 5 </td><td class="markdownTableBodyLeft">jCol[6] = 1 </td><td class="markdownTableBodyLeft">values[6] = 2.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[7] = 5 </td><td class="markdownTableBodyLeft">jCol[7] = 2 </td><td class="markdownTableBodyLeft">values[7] = 5.0  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[8] = 5 </td><td class="markdownTableBodyLeft">jCol[8] = 4 </td><td class="markdownTableBodyLeft">values[8] = 9.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[9] = 5 </td><td class="markdownTableBodyLeft">jCol[9] = 5 </td><td class="markdownTableBodyLeft">values[9] = 1.4  </td></tr>
</table>
<table class="markdownTable">
<tr class="markdownTableHead">
<th class="markdownTableHeadLeft">row </th><th class="markdownTableHeadLeft">col </th><th class="markdownTableHeadLeft">value  </th></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[0] = 0 </td><td class="markdownTableBodyLeft">jCol[0] = 0 </td><td class="markdownTableBodyLeft">values[0] = 1.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[1] = 1 </td><td class="markdownTableBodyLeft">jCol[1] = 1 </td><td class="markdownTableBodyLeft">values[1] = 1.1  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[2] = 2 </td><td class="markdownTableBodyLeft">jCol[2] = 0 </td><td class="markdownTableBodyLeft">values[2] = 3.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[3] = 2 </td><td class="markdownTableBodyLeft">jCol[3] = 2 </td><td class="markdownTableBodyLeft">values[3] = 1.2  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[4] = 3 </td><td class="markdownTableBodyLeft">jCol[4] = 2 </td><td class="markdownTableBodyLeft">values[4] = 6.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[5] = 3 </td><td class="markdownTableBodyLeft">jCol[5] = 3 </td><td class="markdownTableBodyLeft">values[5] = 1.3  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[6] = 4 </td><td class="markdownTableBodyLeft">jCol[6] = 0 </td><td class="markdownTableBodyLeft">values[6] = 2.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[7] = 4 </td><td class="markdownTableBodyLeft">jCol[7] = 1 </td><td class="markdownTableBodyLeft">values[7] = 5.0  </td></tr>
<tr class="markdownTableRowOdd">
<td class="markdownTableBodyLeft">iRow[8] = 4 </td><td class="markdownTableBodyLeft">jCol[8] = 3 </td><td class="markdownTableBodyLeft">values[8] = 9.0  </td></tr>
<tr class="markdownTableRowEven">
<td class="markdownTableBodyLeft">iRow[9] = 4 </td><td class="markdownTableBodyLeft">jCol[9] = 4 </td><td class="markdownTableBodyLeft">values[9] = 1.4  </td></tr>
</table>
<h1><a class="anchor" id="SMARTPTR"></a>
The Smart Pointer Implementation: SmartPtr&lt;T&gt;</h1>
<p>The <a class="el" href="classIpopt_1_1SmartPtr.html" title="Template class for Smart Pointers.">Ipopt::SmartPtr</a> class is described in <a class="el" href="IpSmartPtr_8hpp.html">IpSmartPtr.hpp</a>. It is a template class that takes care of counting references to objects and deleting them when there are no references anymore. Instead of pointing to an object with a raw C++ pointer (e.g. <code>HS071_NLP*</code>), we use a <a class="el" href="classIpopt_1_1SmartPtr.html" title="Template class for Smart Pointers.">Ipopt::SmartPtr</a>. Every time a <code>SmartPtr</code> is set to reference an object, it increments a counter in that object (see the <a class="el" href="classIpopt_1_1ReferencedObject.html" title="Storing the reference count of all the smart pointers that currently reference it.">Ipopt::ReferencedObject</a> base class if you are interested). If a <code>SmartPtr</code> is done with the object, either by leaving scope or being set to point to another object, the counter is decremented. When the count of the object goes to zero, the object is automatically deleted. <code>SmartPtr</code>'s are very simple, just use them as you would use a standard pointer.</p>
<p>It is very important to use <code>SmartPtr</code>'s instead of raw pointers when passing objects to Ipopt. Internally, Ipopt uses smart pointers for referencing objects. If you use a raw pointer in your executable, the object's counter will NOT get incremented. Then, when Ipopt uses smart pointers inside its own code, the counter will get incremented. However, before Ipopt returns control to your code, it will decrement as many times as it incremented earlier, and the counter will return to zero. Therefore, Ipopt will delete the object. When control returns to you, you now have a raw pointer that points to a deleted object.</p>
<p>This might sound difficult to anyone not familiar with the use of smart pointers, but just follow one simple rule; always use a <a class="el" href="classIpopt_1_1SmartPtr.html" title="Template class for Smart Pointers.">Ipopt::SmartPtr</a> when creating or passing an Ipopt object. </p>
</div></div><!-- contents -->
</div><!-- PageDoc -->
</div><!-- doc-content -->
</body>
</html>
